/**
 * @addtogroup brd_uart
 * brd_uart
 * @{
 */
/**
 * @file brd_uart.h
 * @brief 串口板级层
 * @note 串口只作为通讯口, 未参与到具体设备的电源, 复位等管理
 * @par 修改日志
 * <table>
 * <tr><th>Date <th>Version <th>Author <th>Description
 * <tr><td>2020-09-30 <td>1.0 <td>软件工程院 <td>创建初始版本
 * @par 示例
 * @code
 * 构造一个设备.
   Brd_THandle handle =  Brd_UartCreateHandle(Int32 id, rx_buf, sizeof(rx_buf), tx_buf, sizeof(tx_buf));

   Brd_UartSetEventReceiver(handle, xxx);
   Brd_UartSetSentEvent(handle, &event);
   Brd_UartSetRecvEvent(handle, &event);

   Brd_UartOpen(handle, 115200, kBrd_UartParityNone);

   // Brd_UartRead
   // Brd_UartWrite

   Brd_UartClose(handle);
   ...
   Brd_UartFreeHandle(handle);
   ...
 * @endcode
 * @copyright 杭州鸿泉物联网技术股份有限公司
 */

#ifndef _BRD_UART_H_
#define _BRD_UART_H_

#include <ofc_types.h>
#include "brd_common.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * 当有数据收到时调用的函数.注意该函数在中断中调用
 * @param handle: 句柄
 * @return 无返回值
 */
typedef void (*Brd_TOnUartRecv)(Brd_THandle handle);

/**
 * 当有空闲区域可以发送数据时调用该函数.注意该函数在中断中调用
 * @param handle: 句柄
 * @return 无返回值
 */
typedef void (*Brd_TOnUartSent)(Brd_THandle handle);

/**
 * 当有奇偶校验错误时调用该函数.注意该函数在中断中调用
 * @param handle: 句柄
 * @return 无返回值
 */
typedef void (*Brd_TOnUartParityError)(Brd_THandle handle);

/**
 * 当出现帧错误时调用该函数.注意该函数在中断中调用
 * @param handle: 句柄
 * @return 无返回值
 */
typedef void (*Brd_TOnUartFrameError)(Brd_THandle handle);

/**
 * 根据标识创建句柄
 * @note tx_buf, rx_buf需要__attribute__((section("CodeQuickAccess")))修饰
 * @code
 *     __attribute__((section("CodeQuickAccess"))) static UInt8 tx_buf[1024];
 * @endcode
 * @param id: 标识, 参见[brd_def](@ref Brd_TUartIdTag)
 * @param tx_buf: 发送缓冲区,不允许为空
 * @param tx_buf_size: 发送缓冲区的大小
 * @param rx_buf: 接收缓冲区,不允许为空
 * @param rx_buf_size: 接收缓冲区的大小
 * @return 当返回值为非 NULL 时, 表示创建成功, \n
 *         当返回值为 NULL 时, 表示创建失败, 原因为参数错误
 */
Brd_THandle Brd_UartCreate(Int32 id, void *tx_buf, Int32 tx_buf_size, void *rx_buf, Int32 rx_buf_size);

/**
 * 根据标识创建句柄(扩展)
 * @note 本函数只能与 Brd_UartCreate 二选一, 不可同时使用
 *     tx_buf, rx_buf需要__attribute__((section("CodeQuickAccess")))修饰
 * @code
 *     __attribute__((section("CodeQuickAccess"))) static UInt8 tx_buf[1024];
 * @endcode
 * @param id: 标识, 参见[brd_def](@ref Brd_TUartIdTag)
 * @param mode: 串口模式, 参见[brd_def](@ref Brd_TUartModeTag)
 * @param tx_buf: 发送缓冲区,不允许为空
 * @param tx_buf_size: 发送缓冲区的大小
 * @param rx_buf: 接收缓冲区,不允许为空
 * @param rx_buf_size: 接收缓冲区的大小
 * @return 当返回值为非 NULL 时, 表示创建成功, \n
 *         当返回值为 NULL 时, 表示创建失败, 原因为参数错误
 */
Brd_THandle Brd_UartCreateEx(Int32 id, Int32 mode, void *tx_buf, Int32 tx_buf_size,
    void *rx_buf, Int32 rx_buf_size);

/**
 * 释放句柄
 * @param handle: 句柄
 * @return 无返回值
 */
void Brd_UartFree(Brd_THandle handle);

/**
 * 获取标识
 * @param handle: 句柄
 * @return 返回用于创建句柄的标识, 参见[brd_def](@ref Brd_TUartIdTag)
 */
Int32 Brd_UartId(Brd_THandle handle);

/**
 * 获取事件接收者
 * @param handle: 句柄
 * @return 返回事件接收者
 */
void *Brd_UartEventReceiver(Brd_THandle handle);

/**
 * 设置事件接收者
 * @param handle: 句柄
 * @param receiver: 事件接收者
 * @return 无返回值
 */
void Brd_UartSetEventReceiver(Brd_THandle handle, void *receiver);

/**
 * 设置发送完成后触发的事件
 * @note  当事件产生时直接告知用户去处理, 中断函数里面调用本函数, 因此需要用户保持警惕,
 *        切勿处理高延迟或不能在中断里面处理的操作
 * @param handle: 句柄
 * @param on_event: 事件方法
 * @return 无返回值
 */
void Brd_UartSetSentEvent(Brd_THandle handle, Brd_TOnUartSent on_event);

/**
 * 设置接收到数据后触发的事件
 * @note  当事件产生时直接告知用户去处理, 中断函数里面调用本函数, 因此需要用户保持警惕,
 *        切勿处理高延迟或不能在中断里面处理的操作
 * @param handle: 句柄
 * @param on_event: 事件方法
 * @return 无返回值
 */
void Brd_UartSetRecvEvent(Brd_THandle handle, Brd_TOnUartRecv on_event);

/**
 * 设置奇偶校验错误后触发的事件
 * @note  当事件产生时直接告知用户去处理, 中断函数里面调用本函数, 因此需要用户保持警惕,
 *        切勿处理高延迟或不能在中断里面处理的操作
 * @param handle: 句柄
 * @param on_event: 事件方法
 * @return 无返回值
 */
void Brd_UartSetParityErrorEvent(Brd_THandle handle, Brd_TOnUartParityError on_event);

/**
 * 设置帧错误后触发的事件
 * @note  当事件产生时直接告知用户去处理, 中断函数里面调用本函数, 因此需要用户保持警惕,
 *        切勿处理高延迟或不能在中断里面处理的操作
 * @param handle: 句柄
 * @param on_event: 事件方法
 * @return 无返回值
 */
void Brd_UartSetFrameErrorEvent(Brd_THandle handle, Brd_TOnUartFrameError on_event);

/**
 * 打开设备
 * @param handle: 句柄
 * @param baudrate: 波特率,如115200, 9600
 * @param parity: 奇偶位类型,参见[Brd_TUartParityTag](@ref Brd_TUartParityTag)
 * @return 当返回值 >= 0 时, 表示成功 \n
 *         当返回值 < 0 时, 表示失败, 参见[brd_def](@ref Brd_TErrorCodeTag)
 */
Int32 Brd_UartOpen(Brd_THandle handle, Int32 baudrate, Int32 parity);

/**
 * 关闭设备
 * @param handle: 句柄
 * @return 当返回值 >= 0 时, 表示成功 \n
 *         当返回值 < 0 时, 表示失败, 参见[brd_def](@ref Brd_TErrorCodeTag)
 */
Int32 Brd_UartClose(Brd_THandle handle);

/**
 * 获取当前的波特率
 * @param handle: 句柄
 * @return 当返回值 >= 0 时, 表示成功 \n
 *         当返回值 < 0 时, 表示失败, 参见[brd_def](@ref Brd_TErrorCodeTag)
 */
Int32 Brd_UartBaudrate(Brd_THandle handle);

/**
 * 返回当前串口是否已经打开
 * @param handle: 句柄
 * @return 返回 True, 为已打开 \n
 *         返回 False, 为未打开
 */
Bool Brd_UartIsOpen(Brd_THandle handle);

/**
 * 驱动读取数据
 * @param handle: 句柄
 * @param buf: 数据缓存
 * @param size: 缓冲区长度
 * @return 当返回值 >= 0 时, 表示成功并返回实际读取的个数 \n
 *         当返回值 < 0 时, 表示失败参见[brd_def](@ref Brd_TErrorCodeTag)
 */
Int32 Brd_UartRead(Brd_THandle handle, void *buf, Int32 size);

/**
 * 驱动写入数据
 * @param handle: 句柄
 * @param data: 数据指针
 * @param size: 数据长度
 * @return 当返回值 >= 0 时, 表示成功并返回实际发送的个数 \n
 *         当返回值 < 0 时, 表示失败参见[brd_def](@ref Brd_TErrorCodeTag)
 */
Int32 Brd_UartWrite(Brd_THandle handle, const void *data, Int32 size);

/**
 * 返回当前串口是否有数据可以读取
 * @param handle: 句柄
 * @return 返回 True, 表示有数据可以读取 \n
 *         返回 False, 没有数据读取返回false
 */
Bool Brd_UartReadable(Brd_THandle handle);

/**
 * 返回当前串口是否可以写入
 * @param handle: 句柄
 * @return 返回 True, 表示有空间可以写入,
 *         返回 False, 表示没有空间可以写入
 */
Bool Brd_UartWriteable(Brd_THandle handle);

#ifdef __cplusplus
}  ///< extern "C"
#endif

#endif  // _BRD_UART_H_
/**
 * @} 
 */
